/**
 * @file bsp_spi.h
 * @brief SPI驱动 - H743-V2飞控板
 * @author Flight Control Team
 * @date 2025-11-09
 *
 * 硬件配置（参考 reference_firmware/h743_v2_pin_analysis.md）:
 *
 * SPI2 (BMI088 IMU):
 *   - SCK:  PD3 (AF5, 2MHz转换率)
 *   - MISO: PC2 (AF5, 高速)
 *   - MOSI: PC3 (AF5, 高速)
 *   - CS_ACCEL: PD4 (GPIO_OUT, 加速度计片选, 低电平有效)
 *   - CS_GYRO:  PD5 (GPIO_OUT, 陀螺仪片选, 低电平有效)
 *   - DRDY_ACCEL: PC14 (GPIO_EXTI14, 加速度计数据就绪, 下降沿)
 *   - DRDY_GYRO:  PC15 (GPIO_EXTI15, 陀螺仪数据就绪, 下降沿)
 *
 * SPI3 (BMI270 IMU):
 *   - SCK:  PB3 (AF6, 2MHz转换率)
 *   - MISO: PB4 (AF6, 高速)
 *   - MOSI: PD6 (AF5, 高速)
 *   - CS:   PA15 (GPIO_OUT, 片选, 低电平有效)
 *   - DRDY: PB7 (GPIO_EXTI7, 数据就绪, 下降沿)
 */

#ifndef __BSP_SPI_H
#define __BSP_SPI_H

#ifdef __cplusplus
extern "C" {
#endif

#include "stm32h7xx_hal.h"
#include <stdint.h>

/* SPI端口定义 */
typedef enum {
    SPI_PORT_2 = 0,  /* BMI088 (加速度计 + 陀螺仪) */
    SPI_PORT_3,      /* BMI270 */
    SPI_PORT_COUNT
} SPIPort_t;

/* BMI088片选设备定义 */
typedef enum {
    BMI088_ACCEL = 0,  /* 加速度计 (PD4) */
    BMI088_GYRO,       /* 陀螺仪 (PD5) */
    BMI088_DEVICE_COUNT
} BMI088_Device_t;

/* SPI初始化状态 */
typedef struct {
    uint8_t spi2_initialized;
    uint8_t spi3_initialized;
} SPI_Status_t;

/**
 * @brief 初始化所有SPI总线
 * @return 0: 成功, -1: 失败
 */
int BSP_SPI_Init(void);

/**
 * @brief SPI2初始化 (BMI088)
 * @return 0: 成功, -1: 失败
 */
int BSP_SPI2_Init(void);

/**
 * @brief SPI3初始化 (BMI270)
 * @return 0: 成功, -1: 失败
 */
int BSP_SPI3_Init(void);

/**
 * @brief SPI传输（阻塞模式）
 * @param port SPI端口
 * @param tx_data 发送数据缓冲区
 * @param rx_data 接收数据缓冲区
 * @param len 数据长度
 * @return 0: 成功, -1: 失败
 */
int BSP_SPI_Transfer(SPIPort_t port, const uint8_t *tx_data, uint8_t *rx_data, uint16_t len);

/**
 * @brief BMI088片选控制
 * @param device 设备选择 (加速度计/陀螺仪)
 * @param select 1: 选中(拉低CS), 0: 释放(拉高CS)
 */
void BSP_SPI_BMI088_CS(BMI088_Device_t device, uint8_t select);

/**
 * @brief BMI270片选控制
 * @param select 1: 选中(拉低CS), 0: 释放(拉高CS)
 */
void BSP_SPI_BMI270_CS(uint8_t select);

/**
 * @brief 获取SPI初始化状态
 * @param status 状态结构体指针
 */
void BSP_SPI_GetStatus(SPI_Status_t *status);

/**
 * @brief SPI读取单个寄存器
 * @param port SPI端口
 * @param reg 寄存器地址
 * @param data 读取的数据
 * @return 0: 成功, -1: 失败
 */
int BSP_SPI_ReadReg(SPIPort_t port, uint8_t reg, uint8_t *data);

/**
 * @brief SPI写入单个寄存器
 * @param port SPI端口
 * @param reg 寄存器地址
 * @param data 写入的数据
 * @return 0: 成功, -1: 失败
 */
int BSP_SPI_WriteReg(SPIPort_t port, uint8_t reg, uint8_t data);

/**
 * @brief SPI读取多个寄存器
 * @param port SPI端口
 * @param reg 起始寄存器地址
 * @param data 读取的数据缓冲区
 * @param len 读取长度
 * @return 0: 成功, -1: 失败
 */
int BSP_SPI_ReadRegs(SPIPort_t port, uint8_t reg, uint8_t *data, uint16_t len);

#ifdef __cplusplus
}
#endif

#endif /* __BSP_SPI_H */

